package com.microtf.inscription.framework.service.excelXml;

import com.microtf.inscription.framework.service.ExcelReaderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import java.util.HashMap;

public class XmlReaderHandler extends DefaultHandler implements AutoCloseable {
    ThreadLocal<ReadEvent> readEventThreadLocal=new ThreadLocal<>();
    Logger logger = LoggerFactory.getLogger(ExcelReaderService.class);

    String worksheetName = "";
    String worksheetId = "";
    boolean inWorksheet;
    boolean inTable;
    boolean inRow;
    HashMap<Integer, String> sheetHeader = new HashMap<>();
    HashMap<String, String> writeSheetRowData = new HashMap<>();
    boolean inData;
    boolean inCell;
    String dataValue;
    boolean hasValue;
    int colIndex = 0;
    int rowIndex = 0;

    public XmlReaderHandler(ReadEvent readEvent) {
        this.readEventThreadLocal.set(readEvent);
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if (qName.equals("Worksheet")) {
            inWorksheet = true;
            if (attributes != null) {
                worksheetName = attributes.getValue("ss:Name");
                worksheetId = attributes.getValue("ss:ID");
            }
        }
        if (qName.equals("Table")) {
            inTable = true;
        }
        if (qName.equals("Row")) {
            inRow = true;
            rowIndex++;
            if (rowIndex == 1) {
                sheetHeader = new HashMap<>();
            } else {
                writeSheetRowData = new HashMap<>();
            }

        }
        if (inTable && inRow && qName.equals("Cell")) {
            inCell = true;
            dataValue = null;
            hasValue = false;
            if (attributes.getValue("ss:Index") != null) {
                colIndex = Integer.parseInt(attributes.getValue("ss:Index"));
            } else {
                colIndex += 1;
            }
        }
        if (inCell && qName.equals("Data")) {
            hasValue = true;
            inData = true;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if (qName.equals("Worksheet")) {
            inWorksheet = false;
        }
        if (qName.equals("Table")) {
            inTable = false;
        }
        if (qName.equals("Row")) {
            colIndex = 0;
            inRow = false;
            if (rowIndex > 1) {
                ReadEvent readEvent = readEventThreadLocal.get();
                if(readEvent!=null){
                    readEvent.onData(writeSheetRowData);
                }
            }
            writeSheetRowData.clear();

        }
        if (qName.equals("Cell")) {
            if (rowIndex == 1) {
                sheetHeader.put(colIndex, dataValue != null ? dataValue : null);
            } else {
                writeSheetRowData.put(sheetHeader.get(colIndex), dataValue != null ? dataValue : null);
            }
            inCell = false;
            dataValue = null;
        }
        if (inTable && inRow && qName.equals("Data")) {
            inData = false;

        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        dataValue = new String(ch, start, length);
    }

    @Override
    public void close() throws Exception {
        logger.info("ReadHeader close");
        readEventThreadLocal.remove();
    }
}
